package utils;

import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static com.qb.devserv.MainService.mService;

import android.app.ActivityManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.RemoteException;
import android.provider.Settings;
import android.text.TextUtils;

import androidx.core.content.FileProvider;

import com.qb.devserv.R;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.List;

import receiver.UnInstallResultReceiver;

public class AppUtil {
    //判断app是否启动
    public static boolean isAppAlive(Context context, String packageName) {
        ActivityManager activityManager =
                (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> processInfos
                = activityManager.getRunningAppProcesses();
        for (int i = 0; i < processInfos.size(); i++) {
            MyUtil.showLog("isAppAlive","--------processname="+processInfos.get(i).processName);
            if (processInfos.get(i).processName.equals(packageName)) {
                return true;
            }
        }
        return false;
    }
    // 获取app列表
    public static JSONArray getAppList(Context ctx) {
        List<ResolveInfo> ps;
        Intent intent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            ps = ctx.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_ALL);
        } else {
            ps = ctx.getPackageManager().queryIntentActivities(intent, 0);
        }
        JSONArray appList = new JSONArray();
        for(int i=0;i<ps.size();i++) {
            ResolveInfo pa = ps.get(i);
            String name = pa.loadLabel(ctx.getPackageManager()).toString();
            String packageName = pa.activityInfo.packageName;
            Drawable icon = pa.loadIcon(ctx.getPackageManager());
            try {
                PackageInfo pi = ctx.getPackageManager().getPackageInfo(packageName, 0);
                Integer versionCode = pi.versionCode;
                String versionName = pi.versionName;
                Long dtInstall = pi.firstInstallTime;
                Long dtUpdate = pi.lastUpdateTime;
                if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) {
                    //MyUtil.showLog("getAppList",name + " | " + packageName + " | " + versionCode + " | " + versionName);
                    if (packageName.equals("com.qb.devserv.xh") || packageName.equals("com.qb.devserv.hc")) continue;
                    JSONObject app = new JSONObject();
                    // 检查是否有开机自启动应用
                    SharedPreferences SP = ctx.getSharedPreferences("dev_mgt_setting", 0);
                    String autorunApp = SP.getString("autorunApp","");
                    if (autorunApp.equals(packageName)) name = "[开机自启动]"+name;
                    app.put("name",name);
                    app.put("packageName",packageName);
                    ImgUtil iu = new ImgUtil();
                    //app.put("icon",iu.getImgStr(iu.drawable2Bitmap(icon)));
                    app.put("versionCode",versionCode);
                    app.put("versionName",versionName);
                    app.put("dtInstall",MyUtil.transferLongToDate("yyyy-MM-dd HH:mm:ss", dtInstall));
                    app.put("dtUpdate",MyUtil.transferLongToDate("yyyy-MM-dd HH:mm:ss", dtUpdate));
                    appList.put(app);
                } else {
                    //系统应用
                }
            } catch (PackageManager.NameNotFoundException | JSONException e) {
                e.printStackTrace();
            }
        }
        return appList;
    }
    // 安装apk
    public static String installApk(Context ctx,String apkPath) {
        File apkfile = new File(apkPath);
        if (!apkfile.exists()) {
            return "安装文件不存在";
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        Intent install = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:" + ctx.getPackageName()));
        install.setAction(Intent.ACTION_VIEW);
        install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        install.addCategory(Intent.CATEGORY_DEFAULT);
        //判断是否是AndroidN以及更高的版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            try {
                String file_provider = ctx.getString(R.string.file_provider);
                Uri contentUri = FileProvider.getUriForFile(ctx.getApplicationContext(), file_provider, apkfile);
                intent.setAction(Intent.ACTION_VIEW);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
            } catch (Exception e) {
                e.printStackTrace();
                return e.getMessage();
            }
        } else {
            intent.setDataAndType(Uri.fromFile(apkfile), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        try {
            ctx.startActivity(intent);
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }
    // 卸载指定包名的应用
    public static String uninstallApk(Context ctx,String pkName) {
        if (checkApplication(ctx,pkName)) {
            Uri packageURI = Uri.parse("package:" + pkName);
            Intent intent = new Intent(Intent.ACTION_DELETE);
            intent.setData(packageURI);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            try {
                ctx.startActivity(intent);
                return "success";
            } catch (Exception e) {
                e.printStackTrace();
                return e.getMessage();
            }
        } else {
            return "此应用未安装";
        }
    }
    // 判断该包名的应用是否安装
    public static boolean checkApplication(Context ctx,String packageName) {
        if (packageName == null || "".equals(packageName)) {
            return false;
        }
        try {
            ctx.getPackageManager().getApplicationInfo(packageName,PackageManager.GET_UNINSTALLED_PACKAGES);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }
    //通过包名启动应用
    public static String startAppByPackage(Context ctx,String pkName) {
        MyUtil.showLog("startAppByPackage",pkName);
        Intent intent = ctx.getPackageManager().getLaunchIntentForPackage(pkName);
        try {
            ctx.startActivity(intent);
            return "success";
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
    }
    // 静默安装apk
    public static String installApkSilent(Context ctx, String path) {
        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder errorMsg = new StringBuilder();
        try {
            //-i 指定安装程序包名称 , -r 覆盖安装 -d 阶级安装
            process = new ProcessBuilder("pm", "install", "-i", ctx.getPackageName(), "-r", "-d", path).start();
            successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
            errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String line;
            while ((line = successResult.readLine()) != null) {
                successMsg.append(line);//.append("\n")
            }
            while ((line = errorResult.readLine()) != null) {
                errorMsg.append(line);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            try {
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
                if (process != null) {
                    process.destroy();
                }
            } catch (Throwable e) { }
        }

        if (!TextUtils.isEmpty(successMsg.toString()) && successMsg.toString().toLowerCase().contains("success")){
            //安装成功
            MyUtil.showLog("installApkSilent 安装成功",successMsg);
            return "success";
        }else{
            //安装失败
            MyUtil.showLog("installApkSilent 安装失败",errorMsg);
            return errorMsg.toString();
        }
    }
    // 静默卸载apk
    public static String uninstallApkSilent(String pkName) {
        MyUtil.showLog("uninstallApkSilent", pkName);
        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder errorMsg = new StringBuilder();
        try {
            process = new ProcessBuilder("pm", "uninstall", "-k", pkName).start();
            successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
            errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            String s;
            while ((s = successResult.readLine()) != null) {
                successMsg.append(s);
            }
            while ((s = errorResult.readLine()) != null) {
                errorMsg.append(s);
            }
            MyUtil.showLog("uninstallApkSilent1",successMsg);
            MyUtil.showLog("uninstallApkSilent1",errorMsg);
        } catch (Exception e) {
            MyUtil.showLog("uninstallApkSilent3",e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (Exception e) {
                MyUtil.showLog("uninstallApkSilent4",e.getMessage());
                e.printStackTrace();
            }
            if (process != null) {
                process.destroy();
            }
        }
        if (!TextUtils.isEmpty(successMsg.toString()) && successMsg.toString().toLowerCase().contains("success")){
            MyUtil.showLog("uninstallApkSilent 卸载成功",successMsg);
            return "success";
        }else{
            MyUtil.showLog("uninstallApkSilent 卸载失败",errorMsg);
            return errorMsg.toString();
        }
    }

    public static String uninstallApkSilent2(String szPackage){
        MyUtil.showLog("uninstallApkSilent2", szPackage);
        InputStream inputStream = null;
        String[] args = { "pm", "uninstall", "-k", szPackage};
        ProcessBuilder processBuilder = new ProcessBuilder(args);
        try{
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            int read=-1;
            Process process = processBuilder.start();
            InputStream errIs = process.getErrorStream();
            while((read = inputStream.read()) != -1){
                outputStream.write(read);
            }
            inputStream = process.getInputStream();
            while((read = inputStream.read()) != -1){
                outputStream.write(read);
            }
            MyUtil.showLog("uninstallApkSilent2 卸载成功",new String(outputStream.toByteArray()));
            return "success";
        }catch (Exception e){
            MyUtil.showLog("uninstallApkSilent2 卸载失败", e.getMessage());
            return e.getMessage();
        }
    }

    public static String uninstallApkSilent3(Context ctx,String packageName) {
        if (checkApplication(ctx,packageName)) {
            MyUtil.showLog("uninstallApkSilent3", packageName);
            try {
                PackageManager pm = ctx.getPackageManager();
                Method[] methods = pm!=null?pm.getClass().getDeclaredMethods():null;
                Method mDel = null;
                if (methods != null && methods.length > 0) {
                    for (Method method : methods) {
                        if (method.getName().toString().equals("deletePackage")) {
                            mDel = method;
                            break;
                        }
                    }
                }
                if (mDel != null) {
                    try {
                        mDel.setAccessible(true);
                        mDel.invoke(pm,packageName,null,0);
                    } catch (Exception e) {
                        return e.getMessage();
                    }
                }
                return "success";
            } catch (Exception e) {
                e.printStackTrace();
                return e.getMessage();
            }
        } else {
            return "此应用未安装";
        }
    }

    public static String uninstallApkSilent4(Context ctx,String pkName) {
        if (checkApplication(ctx,pkName)) {
            MyUtil.showLog("uninstallApkSilent4", pkName);
            Intent broadcastIntent = new Intent(ctx, UnInstallResultReceiver.class);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 1,broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            PackageInstaller packageInstaller = ctx.getPackageManager().getPackageInstaller();
            packageInstaller.uninstall(pkName, pendingIntent.getIntentSender());
            return "success";
        } else {
            return "此应用未安装";
        }
    }

    public static String uninstallApkSilent5(Context ctx, String name) {
        MyUtil.showLog("uninstallApkSilent5", name);
        String path = getApkPathByPackageName(ctx,name);
        MyUtil.showLog("uninstallApkSilent5", path);
        if (path.equals("fail")) {
            return "此应用未安装";
        } else {
            class InstallResultReceiver extends BroadcastReceiver {
                @Override
                public void onReceive(Context context, Intent intent) {
                    MyUtil.showLog("uninstallApkSilent5","onReceive");
                }
            }
            Intent broadcastIntent = new Intent(ctx, InstallResultReceiver.class);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 1,broadcastIntent, FLAG_IMMUTABLE);
            PackageInstaller packageInstaller = ctx.getPackageManager().getPackageInstaller();
            packageInstaller.uninstall(path, pendingIntent.getIntentSender());
            return "success";
        }
    }

    public static String getApkPathByPackageName(Context ctx, String packageName) {
        MyUtil.showLog("getApkPathByPackageName", packageName);
        try {
            PackageManager packageManager = ctx.getPackageManager();
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, 0);
            return applicationInfo.sourceDir;//获取APK路径
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return "fail";
        }
    }
}
